package ru.compscicenter.databases.zaikina.common;

import ru.compscicenter.databases.zaikina.common.model.WordWithReferences;
import ru.compscicenter.databases.zaikina.common.model.Word;

import java.io.*;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;

public class TextFile {
    private String text = "";
    private ArrayList<WordWithReferences> list;
    private final Integer fileId;

    public TextFile(Integer fileId, String path) {
        this.fileId = fileId;
        load(path);
    }

    private String load(String path) {
        BufferedReader reader;
        try {
            reader = new BufferedReader(new FileReader(path));
            //reader = new BufferedReader(new InputStreamReader(new URL(path).openStream()));
        } catch (Exception ex) {
            return "";
        }

        String line;
        try {
            while((line = reader.readLine()) != null) {
                text += (line + " ");
            }
            reader.close();
        } catch (IOException e) {
            return "";
        }
        return text;
    }

    public String getText() {
        return text;
    }

    private ArrayList<WordWithReferences> splitText() {
        HashMap<String, Integer> words = new HashMap<String, Integer>();
        list = new ArrayList<WordWithReferences>();

        text = text.replaceAll("[^a-zA-Z-']+", "   ").toUpperCase();
        String[] separatedText = text.split(" ");
        for (String word : separatedText) {
            if (word == null || word.length() == 0 || word.charAt(0) < 'A' || word.charAt(0) > 'Z') {
                continue;
            }

            if (!words.containsKey(word)) {
                words.put(word, list.size());
                list.add(new WordWithReferences(new Word(word)));
            } else {
                int idx = words.get(word);
                list.get(idx).addNewReference(fileId);
            }
        }
        return list;
    }

    public ArrayList<WordWithReferences> parse() {
        if (list != null) {
            return list;
        }

        return splitText();
    }
}
